# Final Fantasy TAS development scripts
# 
# Copyright notice for this file:
#  Copyright (C) 2010 TheAxeMan
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


#This had something to do with importing in the python shell
import sys
if globals().has_key('init_modules'):
  for m in [x for x in sys.modules.keys() if x not in init_modules]:
    del(sys.modules[m])
else:
  init_modules = sys.modules.keys()


import sys
import re
import string

from gamedata import GameData
from gamestate import GameState
from rundata import RunSegment
from rundata import RunSegments
from metarundata import MetaRunSegment
from metarundata import MetaRunSegments
from resultdata import ResultSegment
from resultdata import ResultSegments
from simulation import *
from costfunctions import CostFunction

def test_cost_function():
  """
  Tests interactions between several of the modules. 
  Makes sure fight list and ResultSegments simulation are identical.
  Also compares cost function results from fight list and ResultsSegments.
  """
  gdata = GameData()
  gdata.loadData()
  gstate = GameState()

  cost_func = CostFunction(gdata)

  #first, load up the run information
  metarun = MetaRunSegments()
  metarun.loadFromFile("parsetest.txt", gdata)
  #metarun.printRun()

  pcount = metarun.permutationCount()
  print "permutation count is", pcount
  cost_func_results = []
  for seed in range(pcount):
    run = metarun.makeRunSegments(seed)
    gstate.powerCycle()

    fight_list = getFightListFromSegments(run, gdata, gstate)
    fl_cost = cost_func.costFunctionByFightList(run, fight_list)

    gstate.powerCycle()
    results = getResultsFromSegments(run, gdata, gstate)
    r_cost = cost_func.costFunctionFromResults(results)

    #compare to fight list
    results.compareToFightList(fight_list)

    if fl_cost != r_cost:
      print "error!! Fight list generated cost of", fl_cost, "vs",r_cost, "for results on seed",seed

    cost_func_results.append(fl_cost)
    #print cost, results.totalEncounters(), results.noRunFightCount(gdata),
  return


def main():
  #load game data
  gdata = GameData()
  gdata.loadData()
  #init game state
  gstate = GameState()
  gstate.powerCycle()

  #load up cost function
  cost_func = CostFunction(gdata)

  #first, load up the run information
  metarun = MetaRunSegments()
  metarun.loadFromFile("published110run.txt", gdata)
  metarun.resetOptionSet()
  #metarun.printRun()

  #metarun.printRun(gdata, True)
  #metarun.printOptionStatus()
  #print metarun.permutationCount()

  #if True:
  if False:
    #old way
    cost_func_results = getCostsForAllSeeds1(metarun, cost_func, gdata, gstate)
  else:
    #fast new way
    tree_sim = TreeSimNode()
    cost_func_results = tree_sim.getCostsForAllSeeds(metarun, cost_func, gdata, gstate)
    #DEBUG: requires fight count debug on
    #fight_counts = []
    #for i in range(len(cost_func_results)/2):
    #  cost_func_results.append(cost_func_results.pop(0))
    #  fight_counts.append(cost_func_results.pop(0))

  #print cost_func_results

  min_cost = cost_func_results[0]
  min_cost_seed = 0
  pcount = metarun.permutationCount()
  for seed in range(pcount):
    if cost_func_results[seed] <= min_cost:
      min_cost = cost_func_results[seed]
      min_cost_seed = seed

  print "best seed is", min_cost_seed, "with a cost of", min_cost
  #DEBUG
  #print "there were",fight_counts[min_cost_seed],"fights"

  #get full results with notes
  best_run = metarun.makeRunSegments(min_cost_seed, True)
  option_cost = metarun.optionCosts()
  results = getResultsFromSegments(best_run, gdata, gstate)

  #print out some stats
  print "the best run is", results.totalSteps(), "steps long and has", results.totalEncounters(), "encounters"
  print "there are", results.noRunFightCount(gdata), "no-run fights and", results.shadowFightCount(gdata), "shadow fights"

  #calculate cost
  #cost = cost_func.costFunctionFromResults(results)
  cost = cost_func.costFunctionFromResultsVerbose(results, gdata)
  
  print "cost function result: ", cost
  print "option cost: ", option_cost
  print "total: ", cost+option_cost

  result_string = results.getReport(gdata)
  result_string += """
This result has """+str(results.totalSteps())+ """ steps and """+ str(results.totalEncounters())+ """ encounters
there are """ + str(results.noRunFightCount(gdata))+""" no-run fights and """ +str(results.shadowFightCount(gdata))+ """ shadow fights

cost function result: """+ str(cost) + """
option cost: """+ str(option_cost) + """
final cost: """+ str(cost+option_cost) +"""

simulated """+str(pcount)+""" different permutations to get this
"""

  #print result_string
  report_file = open("ffpf_results.txt", "w")
  report_file.write(result_string)
  report_file.close()

  return
  

if __name__ == "__main__":
  main()

